package com.ycq.parser.node.parser;

import com.ycq.parser.ImageInfo;
import com.ycq.parser.QuestionNode;
import com.ycq.parser.attribute.AttributeNode;
import com.ycq.parser.node.RadioQuestionNode;
import org.apache.commons.lang3.StringUtils;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 单选题解析器
 *
 * @author ycq
 * @date 2025/9/24 15:18
 */
public class RadioQuestionParser implements ParserProvider {

    private static Pattern CODE_PATTERN = Pattern.compile("^((\\d{1,3})(\\.|、)?).+");
    private static Pattern EXCLUDE_WORD_PATTERN = Pattern.compile("((\\d{1,3})(~|～|-)(\\d{1,3})).+");


    @Override
    public boolean hasSupport(List<String> questionItemLines) {

        /*
              判断题目顺序是否是 ，序号、问题 ，选项，答案，并且答案中的值是一个字母
         */
        Iterator<String> iterator = questionItemLines.iterator();

        // 第一行
        if (iterator.hasNext()) {
            String next = iterator.next();

            // 排除共享类题目
            if (EXCLUDE_WORD_PATTERN.matcher(next).matches()) {
                return false;
            }

            // 题目格式不符合单选
            Matcher matcher = CODE_PATTERN.matcher(next);
            if (!matcher.matches()) {
                return false;
            }

            // 获取序号
            String code = "";
            matcher = CODE_PATTERN.matcher(next);
            if (matcher.find()) {
                code = matcher.group(1);
            }

            // 问题为空
            String question = next.substring(code.length());
            if (StringUtils.isBlank(question)) {
                return false;
            }
        }

        Set<String> optionsZM = new java.util.HashSet<>();
        while (iterator.hasNext()) {
            String next = iterator.next();

            // 不是字母
            char c = next.charAt(0);
            if (Character.isLetter(c)) {
                optionsZM.add(String.valueOf(c));
            } else {
                if (next.trim().startsWith("【答案】")) {
                    // 答案
                    String answer = next.trim().substring("【答案】".length()).trim();

                    if (answer.length() != 1) {
                        return false;
                    }

                    if (optionsZM.contains(answer)) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    @Override
    public QuestionNode parse(List<String> questionItemLines, List<ImageInfo> imageInfoNode) {

        // 检查是否有多个题中间没有空行，而导致解析成一道题
        checkMultiQuestion(questionItemLines);

        RadioQuestionNode radioQuestionNode = new RadioQuestionNode();
        String question = questionItemLines.get(0);
        Matcher matcher = CODE_PATTERN.matcher(question);
        if (matcher.find()) {
            String group = matcher.group(1);
            radioQuestionNode.setQuestionCode(matcher.group(2));
            question = question.substring(group.length());
        }

        radioQuestionNode.setQuestion(question);
        radioQuestionNode.setImages(imageInfoNode);
        radioQuestionNode.setRawLines(questionItemLines);

        List<String> questionOptions = new java.util.ArrayList<>();
        Map<String, AttributeNode> questionAttributes = new java.util.HashMap<>();

        for (int i = 1; i < questionItemLines.size(); i++) {
            String line = questionItemLines.get(i).trim();
            char c = line.charAt(0);
            if (isLetter(c)) {
                questionOptions.add(line);
            } else {

                // 判断是否为属性
                AtomicReference<String> attributeName = new AtomicReference<>(null);
                GenericTokenParser genericTokenParser = new GenericTokenParser("【", "】", new GenericTokenParser.TokenHandler() {
                    @Override
                    public String handleToken(String content) {
                        attributeName.set(content);
                        return "";
                    }
                });
                String parsedValue = genericTokenParser.parse(line);
                if (attributeName.get() != null) {
                    String attrKey = attributeName.get();
                    attributeName.set(null);

                    int offsetStartIndex = i+1;
                    int offsetEndIndex = offsetStartIndex;
                    while (offsetEndIndex < questionItemLines.size()) {
                        String nextLine = questionItemLines.get(offsetEndIndex).trim();
                        genericTokenParser.parse(nextLine);
                        if (attributeName.get() != null) {
                            break;
                        }
                        offsetEndIndex++;
                    }

                    if(offsetStartIndex<offsetEndIndex){
                        // 截取子集合
                        List<String> lines = questionItemLines.subList(offsetStartIndex, offsetEndIndex);
                        String joined = String.join("\n", lines);
                        joined = StringUtils.isNotBlank(parsedValue) ? parsedValue+"\n"+joined : joined;
                        questionAttributes.put(attrKey, new AttributeNode(joined, joined));
                        i = offsetEndIndex - 1;
                    }else{
                        questionAttributes.put(attrKey, new AttributeNode(line, parsedValue));
                    }
                }
            }
        }

        radioQuestionNode.setAttributes(questionAttributes);
        radioQuestionNode.setQuestionOptions(questionOptions);
        return radioQuestionNode;
    }

    private void checkMultiQuestion(List<String> questionItemLines) {
        int count = 0;
        for (String questionItemLine : questionItemLines) {
            String trimmed = questionItemLine.trim();
            if(trimmed.startsWith("【答案】")){
                count++;
            }
        }

        // 单选只能有一个题，出现多题，抛出异常
        if(count > 1){
            throw new RuntimeException("单选只能有一个题，出现多题，抛出异常， >>> \n--------context------   \n"+ String.join("\n",questionItemLines)+"\n--------------");
        }
    }

    private boolean isLetter(char c) {
        return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
    }
}
